package com.lancoo.cvas.arrangecourse.dataprocess;

import com.lancoo.cvas.pojo.dto.*;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description TODO
 * @Author Fortysun
 * @Date 2023-03-27 11:32
 */
@Slf4j
public class TeacherAndCourseProhibitProcess extends GenerateSchedulingData {

    public TeacherAndCourseProhibitProcess() {

    }


    /**
     * 获取禁排之后的教学班列表信息
     *
     * @param teachingClassList  教学班信息列表
     * @param courseProhibitList 课程禁排列表
     * @param teacherRuleList    教师规则列表,注意，此处传入的，应该是过滤后的，只有禁排规则的教师规则列表信息
     * @return
     */
    public List<ArrangeTeachingClassDto> getResult(List<ArrangeTeachingClassDto> teachingClassList,
                                                   List<ArrangeCourseRuleDto> courseProhibitList,
                                                   List<ArrangeTeacherRuleDto> teacherRuleList,
                                                   List<ArrangeClassRuleDto> classRuleList,
                                                   List<ArrangeTeachingClassRuleDto> teachingClassRuleList) {
        if (teachingClassList == null || teachingClassList.isEmpty()) {
            log.error("TeacherAndCourseProhibitProcess--getResult: 教学班数据获取失败了~！！");
            return null;
        }

        //课程禁排处理；
        teachingClassList = courseProhibitProcess(teachingClassList, courseProhibitList);
        //教师禁排处理；
        teachingClassList = teacherProhibitPorcess(teachingClassList, teacherRuleList);
        //行政班禁排处理；
        teachingClassList = classProhibitProcess(teachingClassList, classRuleList);
        //教学班禁排处理；
        teachingClassList = teachingClassProhibitPorcess(teachingClassList, teachingClassRuleList);

        return teachingClassList;
    }

    /**
     * 处理教学班列表的行政班禁排规则
     *
     * @param teachingClassList 教学班列表信息
     * @param classRuleList     行政班规则列表信息
     * @return
     */
    private List<ArrangeTeachingClassDto> classProhibitProcess(List<ArrangeTeachingClassDto> teachingClassList,
                                                               List<ArrangeClassRuleDto> classRuleList) {

        if (classRuleList != null && !classRuleList.isEmpty()) {
            //筛选出行政班禁排的规则
            List<ArrangeClassRuleDto> classProhibitRuleList = classRuleList.stream()
                    .filter(rule -> rule.getFlag().equals(2))//筛选出行政班禁排的规则
                    .collect(Collectors.toList());
            if (classProhibitRuleList != null && !classProhibitRuleList.isEmpty()) {
                log.info("#TeacherAndCourseProhibitProcess.classProhibitPorcess#--共获取行政班禁排数据{}条",
                        (classProhibitRuleList != null ? classProhibitRuleList.size() : 0));

                for (ArrangeClassRuleDto classRule : classProhibitRuleList) {
                    for (ArrangeTeachingClassDto teachingClass : teachingClassList) {
                        if (isTeacherIdExist(teachingClass.getClassId(), classRule.getClassId() + "")) {
                            //将行政班禁排的课时，标记到对应的教学班信息中
                            teachingClass.setProhibitTimeslotCodes(dealTimeslotCodes(teachingClass.getProhibitTimeslotCodes(),
                                    classRule.getTimeCode()));
                        }
                    }
                }
            }
        }


        return teachingClassList;
    }

    /**
     * 处理教学班列表的教学班禁排规则
     *
     * @param teachingClassList     教学班列表信息
     * @param teachingClassRuleList 教学班规则列表信息
     * @return
     */
    private List<ArrangeTeachingClassDto> teachingClassProhibitPorcess(List<ArrangeTeachingClassDto> teachingClassList,
                                                                       List<ArrangeTeachingClassRuleDto> teachingClassRuleList) {

        if (teachingClassRuleList != null && !teachingClassRuleList.isEmpty()) {
            //筛选出教学班禁排的规则
            List<ArrangeTeachingClassRuleDto> teachingClassProhibitRuleList = teachingClassRuleList.stream()
                    .filter(rule -> rule.getFlag().equals(2))//筛选出教学班禁排的规则
                    .collect(Collectors.toList());
            if (teachingClassProhibitRuleList != null && !teachingClassProhibitRuleList.isEmpty()) {
                log.info("#TeacherAndCourseProhibitProcess.teachingClassProhibitPorcess#--共获取教学班禁排数据{}条",
                        (teachingClassProhibitRuleList != null ? teachingClassProhibitRuleList.size() : 0));

                for (ArrangeTeachingClassRuleDto teachingClassRule : teachingClassProhibitRuleList) {
                    for (ArrangeTeachingClassDto teachingClass : teachingClassList) {
                        if (teachingClass.getTeachingClassId().equals(teachingClassRule.getTeachingClassId())) {
                            //将教学班禁排的课时，标记到对应的教学班信息中
                            teachingClass.setProhibitTimeslotCodes(dealTimeslotCodes(teachingClass.getProhibitTimeslotCodes(),
                                    teachingClassRule.getTimeCode()));
                        }
                    }
                }
            }
        }


        return teachingClassList;
    }

    /**
     * 处理教学班列表的课程禁排
     *
     * @param teachingClassList 教学班信息列表
     * @param courseRuleList    课程排课规则列表
     * @return
     */
    private List<ArrangeTeachingClassDto> courseProhibitProcess(List<ArrangeTeachingClassDto> teachingClassList,
                                                                List<ArrangeCourseRuleDto> courseRuleList) {
        if (courseRuleList != null && !courseRuleList.isEmpty()) {
            //筛选出课程禁排的规则
            List<ArrangeCourseRuleDto> courseProhibitList = courseRuleList.stream()
                    .filter(rule -> rule.getFlag().equals(2))//筛选出课程禁排的规则
                    .collect(Collectors.toList());

            if (courseProhibitList != null && !courseProhibitList.isEmpty()) {
                log.info("#TeacherAndCourseProhibitProcess.courseProhibitProcess#--共获取课程禁排数据{}条",
                        (courseProhibitList != null ? courseProhibitList.size() : 0));
                for (ArrangeCourseRuleDto courseProhibit : courseProhibitList) {
                    for (ArrangeTeachingClassDto teachingClass : teachingClassList) {
                        //如果课程id相等，教学班相等，处理课程的禁排信息；
                        if (courseProhibit.getCourseId().equals(teachingClass.getCourseId())
                                && courseProhibit.getTeachingClassId().equals(teachingClass.getTeachingClassId())) {
                            //为对应的教学班，设置禁排的课时
                            teachingClass.setProhibitTimeslotCodes(
                                    dealTimeslotCodes(teachingClass.getProhibitTimeslotCodes(),
                                            courseProhibit.getTimeCode()));
                        }
                    }
                }
            }

        }

        return teachingClassList;
    }

    /**
     * 处理生成的禁排课时字符串，用逗号分割
     *
     * @param prohibitTimeslotCodes    禁排字符串
     * @param newProhibitTimeslotCodes 需要加入的禁排课时
     * @return
     */
    private String dealTimeslotCodes(String prohibitTimeslotCodes, String newProhibitTimeslotCodes) {
        if (prohibitTimeslotCodes == null) {
            prohibitTimeslotCodes = "";
        }
        if (!prohibitTimeslotCodes.contains(newProhibitTimeslotCodes)) {
            prohibitTimeslotCodes += newProhibitTimeslotCodes + ",";
        }
        return prohibitTimeslotCodes;
    }

    /**
     * 处理教学班列表的教师禁排规则
     *
     * @param teachingClassList 教学班列表信息
     * @param teacherRuleList   教师规则列表信息
     * @return
     */
    private List<ArrangeTeachingClassDto> teacherProhibitPorcess(List<ArrangeTeachingClassDto> teachingClassList,
                                                                 List<ArrangeTeacherRuleDto> teacherRuleList) {

        if (teacherRuleList != null && !teacherRuleList.isEmpty()) {
            //筛选出教师禁排的规则
            List<ArrangeTeacherRuleDto> teacherProhibitRuleList = teacherRuleList.stream()
                    .filter(rule -> rule.getFlag().equals(2))//筛选出教师禁排的规则
                    .collect(Collectors.toList());
            if (teacherProhibitRuleList != null && !teacherProhibitRuleList.isEmpty()) {
                log.info("#TeacherAndCourseProhibitProcess.teacherProhibitPorcess#--共获取教师禁排数据{}条",
                        (teacherProhibitRuleList != null ? teacherProhibitRuleList.size() : 0));

                for (ArrangeTeacherRuleDto teacherRule : teacherProhibitRuleList) {
                    for (ArrangeTeachingClassDto teachingClass : teachingClassList) {
                        if (isTeacherIdExist(teachingClass.getTeacherIds(), teacherRule.getTeacherId() + "")) {
                            //将教师禁排的课时，标记到对应的教学班信息中
                            teachingClass.setProhibitTimeslotCodes(dealTimeslotCodes(teachingClass.getProhibitTimeslotCodes(),
                                    teacherRule.getTimeCode()));
                        }
                    }
                }
            }
        }


        return teachingClassList;
    }


    /**
     * 处理单个教学班的课程禁排
     *
     * @param teachingClass      教学班信息
     * @param courseProhibitList 课程禁排列表
     * @return
     */
    private ArrangeTeachingClassDto courseProhibitProcess(ArrangeTeachingClassDto teachingClass,
                                                          List<ArrangeCourseRuleDto> courseProhibitList) {
        if (courseProhibitList != null && !courseProhibitList.isEmpty()) {
            for (ArrangeCourseRuleDto courseProhibit : courseProhibitList) {
                //如果课程id相等，教学班相等，处理课程的禁排信息；
                if (courseProhibit.getCourseId().equals(teachingClass.getCourseId())
                        && courseProhibit.getTeachingClassId().equals(teachingClass.getTeachingClassId())) {
                    //为对应的教学班，设置禁排的课时
                    teachingClass.setProhibitTimeslotCodes(
                            dealTimeslotCodes(teachingClass.getProhibitTimeslotCodes(),
                                    courseProhibit.getTimeCode()));
                }
            }
        }

        return teachingClass;
    }

    /**
     * 处理单个教学班的教师禁排规则
     *
     * @param teachingClass   教学班信息
     * @param teacherRuleList 教师规则列表信息
     * @return
     */
    private ArrangeTeachingClassDto teacherProhibitPorcess(ArrangeTeachingClassDto teachingClass,
                                                           List<ArrangeTeacherRuleDto> teacherRuleList) {

        if (teacherRuleList != null && !teacherRuleList.isEmpty()) {
            for (ArrangeTeacherRuleDto teacherRule : teacherRuleList) {
                if (isTeacherIdExist(teachingClass.getTeacherIds(), teacherRule.getTeacherId() + "")) {
                    //将教师禁排的课时，标记到对应的教学班信息中
                    teachingClass.setProhibitTimeslotCodes(dealTimeslotCodes(teachingClass.getProhibitTimeslotCodes(),
                            teacherRule.getTimeCode()));
                }
            }
        }

        return teachingClass;
    }

    /**
     * 处理单个教学班的教师禁排规则
     *
     * @param teachingClass   教学班信息
     * @param classRuleList 行政班规则列表信息
     * @return
     */
    private ArrangeTeachingClassDto classProhibitPorcess(ArrangeTeachingClassDto teachingClass,
                                                           List<ArrangeClassRuleDto> classRuleList) {

        if (classRuleList != null && !classRuleList.isEmpty()) {
            for (ArrangeClassRuleDto classRule : classRuleList) {
                if (isTeacherIdExist(teachingClass.getClassId(), classRule.getClassId() + "")) {
                    //将教师禁排的课时，标记到对应的教学班信息中
                    teachingClass.setProhibitTimeslotCodes(dealTimeslotCodes(teachingClass.getProhibitTimeslotCodes(),
                            classRule.getTimeCode()));
                }
            }
        }

        return teachingClass;
    }

    /**
     * 处理单个教学班的教师禁排规则
     *
     * @param teachingClass   教学班信息
     * @param classRuleList 行政班规则列表信息
     * @return
     */
    private ArrangeTeachingClassDto teachingClassProhibitPorcess(ArrangeTeachingClassDto teachingClass,
                                                                 List<ArrangeTeachingClassRuleDto> teachingClassProhibitList) {

        if (teachingClassProhibitList != null && !teachingClassProhibitList.isEmpty()) {
            for (ArrangeTeachingClassRuleDto teachingClassRule : teachingClassProhibitList) {
                if (teachingClass.getTeachingClassId().equals(teachingClassRule.getTeachingClassId())) {
                    //将教师禁排的课时，标记到对应的教学班信息中
                    teachingClass.setProhibitTimeslotCodes(dealTimeslotCodes(teachingClass.getProhibitTimeslotCodes(),
                            teachingClassRule.getTimeCode()));
                }
            }
        }

        return teachingClass;
    }

    /**
     * 获取禁排之后的教学班信息
     *
     * @param teachingClass      教学班信息
     * @param courseProhibitList 课程禁排列表
     * @param teacherRuleList    教师规则列表,注意，此处传入的，应该是过滤后的，只有禁排规则的教师规则列表信息
     * @return
     */
    public ArrangeTeachingClassDto getResult(ArrangeTeachingClassDto teachingClass,
                                             List<ArrangeCourseRuleDto> courseProhibitList,
                                             List<ArrangeTeacherRuleDto> teacherRuleList,
                                             List<ArrangeClassRuleDto> classProhibitList,
                                             List<ArrangeTeachingClassRuleDto> teachingClassProhibitList) {
        if (teachingClass == null) {
            log.error("TeacherAndCourseProhibitProcess--getResult: 教学班数据获取失败了~！！");
            return null;
        }

        //课程禁排处理；
        teachingClass = courseProhibitProcess(teachingClass, courseProhibitList);
        //教师禁排处理；
        teachingClass = teacherProhibitPorcess(teachingClass, teacherRuleList);
        //行政班禁排处理；
        teachingClass = classProhibitPorcess(teachingClass, classProhibitList);
        //教教学班禁排处理；
        teachingClass = teachingClassProhibitPorcess(teachingClass, teachingClassProhibitList);

        return teachingClass;
    }

}
